import Dialog from '@vant/weapp/dialog/dialog';
const amapFile = require('../../libs/bmap-wx.min');
const db = wx.cloud.database();
const newsCollection = db.collection('news');
const deseasenewsCollection = db.collection('Desease_news');

// 常量配置 - 预警等级相关
const SEVERITY_CONFIG = {
  COLOR_MAP: { 1: 'FF0000', 2: 'FFA500', 3: '00FF00' },
  ZOOM_MAP: { 1: 13, 2: 11, 3: 9 }
};

// 新增：音频相关常量配置（集中管理便于维护）
const AUDIO_CONFIG = {
  MAX_TEXT_LENGTH: 500, // 最大文本长度限制（防止音频过大）
  SAMPLE_RATE: 24000,   // 采样率（需与服务器一致）
  TIMEOUT: 60000        // 语音合成超时时间（毫秒）
};

Page({

  /**
   * 页面的初始数据
   */
  data: {
    value: '',
    userNickname: '',
    userAvatar: '',
    show: false,
    dshow: false,
    actions: [],
    deseaseActions: [],
    // 新闻弹出框
    dialogShow: false,
    dialogTitle: '',
    dialogMessage: '',
    dialogLink: '',
    currentPage: 1,    // 当前新闻页码
    pageSize: 20,      // 每页数量
    totalCount: 0,     // 新闻总数据量
    loading: false,     // 新闻加载状态
    hasMore: true,
    dCurrentPage: 1,   // 当前预警页码
    dTotalCount: 0,    // 预警总数据量
    dLoading: false,    // 预警加载状态
    dHasMore: true,
    photo: [],
    // 预警地图信息
    mapshow: false,
    staticMapUrl: '',
    mapZoom: 12,            // 当前地图缩放级别（根据距离动态调整）
    mapLoading: false,      // 地图加载状态（防止重复请求）

    // 经纬度存储
    localLongitude: 0,      // 本地经度（WGS84坐标系）
    localLatitude: 0,       // 本地纬度
    targetLongitude: 0,     // 目标地址经度
    targetLatitude: 0,      // 目标地址纬度

    // 距离相关
    targetAddress: '',      // 目标地址文本（如"河北省张家口市涿鹿县"）
    distanceKm: 0,          // 两地距离（公里，保留2位小数）
    distanceMeters: 0,      // 原始距离（米，高精度）

    // 错误处理
    mapError: false,        // 地图加载失败标记
    geocodeError: false,     // 地理编码失败标记
    loading: false,  // 新增加载状态
    useMsg: '',
    AIloading: false,

    // 音频相关状态（已修复重复定义问题）
    cancelRequest: false,   // 是否取消语音请求
    audioPlaying: false,    // 是否正在播放音频
    tempPcmPath: '',        // 临时PCM文件路径
    tempWavPath: ''         // 临时WAV文件路径
  },

  // 新闻模块获取数据
  async onLoad() {
    this.loadNews();
    this.loadDeseaseNews();
     // 初始化音频上下文（全局唯一，减少内存占用）
     this.initAudioContext();
  },

  async loadNews() {
    const { currentPage, pageSize } = this.data;
    if (this.data.loading) return;

    try {
      this.setData({ loading: true });
      const res = await newsCollection
        .orderBy('date', 'desc')    // 同类型文档按日期降序排列
        .skip((currentPage - 1) * pageSize)
        .limit(pageSize)
        .get();
      const res1 = await newsCollection
        .count();

      const newData = res.data.map(news => ({
        name: news.title,
        subname: news.summary,
        section: news.section,
        date: news.date,
        link: news.link,
        photo: news.photo ? Object.values(news.photo) : [],
      }));
      res.total = res1.total;

      this.setData({
        actions: this.data.actions.concat(newData),
        totalCount: res.total,
        currentPage: currentPage + 1,
        loading: false
      });
    } catch (e) {
      console.error('获取新闻数据失败', e);
      this.setData({ loading: false });
    }
  },

  handleCancel(e) {
    const { currentPage, pageSize, totalCount } = this.data;
    const hasMore = (currentPage - 1) * pageSize < totalCount;
    if (hasMore && !this.data.loading) {
      this.loadNews();
    } else {
      wx.showToast({
        title: '新闻到底啦~',
        icon: 'none'
      });
    }
  },

  onClose() {
    this.setData({ show: false });
  },

  onSelect(event) {
    const newsItem = event.target.dataset.news;
    console.log("newItem", newsItem);
    if (newsItem.subname === "无摘要") newsItem.subname = "";
    const dialogMessage = `${newsItem.section}\n日期: ${newsItem.date}\n${newsItem.subname}\n`;
    this.setData({
      dialogShow: true,
      dialogTitle: newsItem.name,
      dialogMessage,
      dialogLink: newsItem.link // 保存当前新闻的链接
    });
  },

  onConfirm() {
    const link = this.data.dialogLink;
    console.log("link", link);
    if (link) {
      if (wx.openLink) {
        wx.openLink({
          url: link,
          success: () => {
            console.log('跳转成功');
            this.setData({ dialogShow: false });
          },
          fail: (res) => {
            console.error('跳转失败:', res);
            wx.showToast({ title: '跳转失败，请检查链接', icon: 'none' });
          }
        });
      } else {
        wx.showToast({
          title: '当前微信版本过低，不支持跳转外部链接',
          icon: 'none'
        });
      }
    } else {
      wx.showToast({ title: '未找到有效链接', icon: 'none' });
    }
  },

  onCancel() {
    // 点击取消，关闭对话框
    this.setData({ dialogShow: false });
  },

  showActionSheet() {
    this.setData({ show: true });
  },

  onReachBottom() {
    this.handleCancel(); // 调用 handleCancel 方法来判断是否加载更多新闻
  },

  // 预警模块获取数据
  async loadDeseaseNews() {
    const { dCurrentPage, pageSize } = this.data;
    if (this.data.dLoading) return;

    try {
      this.setData({ dLoading: true });
      const res = await deseasenewsCollection
        .orderBy('createTime', 'desc')
        .skip((dCurrentPage - 1) * pageSize)
        .limit(pageSize)
        .get();
      const res1 = await deseasenewsCollection.count();
      console.log("预警新闻的详细数据", res);
      const newData = res.data.map(news => ({
        id: news._id,                 // 新增唯一标识
        name: news.title,             // 预警标题
        severity: news.severity,      // 预警等级（如'high' 'medium' 'low'）
        date: news.date,              // 发布日期
        place: news.place,            // 发生地点
        distanceKm: news.distanceKm || 0, // 距离（从数据库或计算获取）
        link: news.link               // 详情链接
      }));
      let GetData = this.data.deseaseActions.concat(newData);
      GetData = GetData.sort((a, b) => {
        // 获取两个元素的 severity 对应的排序权重
        const orderA = a.severity || 3; // 处理未知值，排到最后
        const orderB = b.severity || 3;

        return orderA - orderB; // 升序排序（从小到大）
      });
      console.log("是否传入了距离值", this.data.deseaseActions.concat(newData));
      this.setData({
        deseaseActions: GetData, // 推入新数组
        dTotalCount: res1.total,
        dCurrentPage: dCurrentPage + 1,
        dLoading: false
      });
    } catch (e) {
      console.error('获取预警数据失败', e);
      this.setData({ dLoading: false });
    }
  },

  formatDate(timeStamp) {
    const date = new Date(timeStamp);
    return date.toLocaleDateString().replace(/\//g, '-');
  },

  dhandleCancel(e) {
    const { dCurrentPage, pageSize, dTotalCount } = this.data;
    const dHasMore = (dCurrentPage - 1) * pageSize < dTotalCount;
    if (dHasMore && !this.data.dLoading) {
      this.loadDeseaseNews();
    } else {
      wx.showToast({
        title: '预警信息到底啦~',
        icon: 'none'
      });
    }
  },

  donClose() {
    this.setData({ dshow: false });
  },

  async onDeseaseSelect(event) {
    this.setData({ loading: true, mapshow: true, AIloading: true });
    try {
      const newsItem = event.currentTarget.dataset.news;
      const targetPlace = newsItem.place;
      const key = 'e0c96471f69462947dba114ab4c93726'; // 高德Web服务key
      // 1. 获取本地经纬度
      const localLocation = await this.getLocalLocation();

      // 2. 获取目标地址经纬度
      const targetGeo = await this.geocodeTargetPlace(targetPlace, key);

      // 3. 计算距离并获取缩放级别
      const distanceKm = await this.calculateDistance(localLocation, targetGeo);
      const zoom = this.getZoomByDistance(distanceKm);
      const markerColor = this.getMarkerColor(distanceKm); // 获取标记颜色
      console.log("更新后的数据", zoom, targetGeo.formattedAddress, distanceKm, markerColor);
      // 4. 生成静态地图URL
      const res = await wx.cloud.callFunction({
        name: 'generateStaticMap',
        data: {
          localLng: localLocation.longitude,
          localLat: localLocation.latitude,
          targetLng: targetGeo.longitude,
          targetLat: targetGeo.latitude,
          zoom,
          color: markerColor
        }
      });
      console.log("经度和纬度", localLocation.longitude, localLocation.latitude, targetGeo.longitude, targetGeo.latitude);
      const staticMapUrl = res.result.url;

      // 5. 更新前端数据
      this.setData({
        staticMapUrl,
        mapZoom: zoom,
        targetAddress: targetGeo.formattedAddress,
        distanceKm: distanceKm, // 绑定距离
        // mapshow: true, // 显示预警地图弹出框（使用 mapshow 而非 show）
        mapError: false, // 清除地图错误状态
        loading: false // 隐藏加载状态
      });
      console.log("更新后的数据", staticMapUrl, zoom, targetGeo.formattedAddress, distanceKm);
      // AI建议模块
      const userMessageContent = `现在发生的情况是${newsItem.name},然后爆发地点是${newsItem.place},我目前处于哈尔滨，灾害距离这里的距离是${distanceKm}公里，请问这个病虫害爆发不会影响我所在的葡萄园？不要使用markdown格式,也不要有欢迎随时向我提问这类的话语`;
      wx.cloud.callFunction({
        name: 'BlueLM-70BAPI',
        data: { prompt: userMessageContent },
        success: res => {
          console.log('云函数调用成功', res.result);
          this.setData({ useMsg: res.result.data, AIloading: false });
        },
        fail: err => {
          console.error('云函数调用失败', err);
          wx.showToast({ title: '获取建议失败', icon: 'none' });
        }
      });
    } catch (error) {
      console.error('操作失败:', error);
      wx.showToast({
        title: error.message || '位置解析失败',
        icon: 'none',
        duration: 2000
      });
      this.setData({ show: false });
    }
  },

  // 获取本地经纬度（封装函数）
  getLocalLocation() {
    return new Promise((resolve, reject) => {
      wx.getLocation({
        type: 'wgs84',
        success: (res) => {
          resolve({
            longitude: res.longitude,
            latitude: res.latitude
          });
        },
        fail: (err) => {
          reject(new Error(`获取本地位置失败: ${err.errMsg}`));
        }
      });
    });
  },

  // 地理编码目标地址（封装函数）
  async geocodeTargetPlace(address) {
    const res = await wx.cloud.callFunction({
      name: 'geocode',
      data: { address }
    });
    const result = res.result;
    if (result.status !== 0) {
      throw new Error(result.message || '目标地址解析失败');
    }
    const { location } = result.result;
    return {
      longitude: location.lng, // 经度
      latitude: location.lat,  // 纬度
      // 若需要完整地址信息，可根据百度地图 API 返回情况调整
      formattedAddress: address
    };
  },

  // 计算距离（封装函数）
  async calculateDistance(local, target) {
    const res = await wx.cloud.callFunction({
      name: 'CalculateDistance',
      data: {
        lat1: local.latitude,
        lon1: local.longitude,
        lat2: target.latitude,
        lon2: target.longitude
      }
    });
    if (res.result.status !== 0) {
      throw new Error(res.result.message || '距离计算失败');
    }
    return res.result.distance.kilometers;
  },

  // 根据距离获取标记颜色
  getMarkerColor(distanceKm) {
    if (distanceKm <= 100) return '0xFF0000'; // 红色（100公里内）
    if (distanceKm <= 500) return '0xFFA500'; // 黄色（500公里内）
    return '0x00FF00'; // 绿色（500公里外）
  },

  // 根据距离获取缩放级别
  getZoomByDistance(distanceKm) {
    if (distanceKm < 1) return 16;    // 1公里内
    if (distanceKm < 100) return 9;   // 100公里内
    if (distanceKm < 500) return 8;   // 500公里内
    if (distanceKm < 1000) return 7;   // 1000公里内
    if (distanceKm < 2000) return 5;   // 2000公里内
    return 3; // 5000公里外
  },

  // 关闭地图弹出框
  onDClose() {
    this.setData({ mapshow: false, staticMapUrl: '' });
  },

  showDeseaseActionSheet() {
    this.setData({ dshow: true });
  },
  // 音频播放相关界面
  /**
   * 初始化音频上下文（复用逻辑，避免重复创建）
   */
  initAudioContext() {
    if (!this.audioCtx) {
      this.audioCtx = wx.createInnerAudioContext();
      // 监听音频自然结束
      this.audioCtx.onEnded(() => {
        this.setData({ audioPlaying: false });
        this.cleanupAudio(); // 播放结束后清理资源
      });
      // 监听手动停止
      this.audioCtx.onStop(() => {
        this.setData({ audioPlaying: false });
        this.cleanupAudio();
      });
      // 监听播放错误
      this.audioCtx.onError((err) => {
        console.error('音频播放失败:', err);
        wx.showToast({ title: '播放失败', icon: 'none' });
        this.setData({ audioPlaying: false });
        this.cleanupAudio();
      });
    }
  },

  /**
   * 点击语音图标，调用服务器合成音频并播放
   */
  synthesizeSpeech() {
    const text = this.data.useMsg;
    // 文本为空校验
    if (!text.trim()) {
      wx.showToast({ title: '暂无AI建议内容', icon: 'none' });
      return;
    }
    // 文本长度限制（防止音频过大）
    const MAX_TEXT_LENGTH = 500;
    if (text.length > MAX_TEXT_LENGTH) {
      wx.showToast({
        title: `文本过长（超过${MAX_TEXT_LENGTH}字）`,
        icon: 'none'
      });
      return;
    }
    // 防止重复请求
    if (this.data.AIloading) return;

    this.setData({ 
      AIloading: true, 
      cancelRequest: false,
      audioPlaying: false 
    });

    // 保存请求任务，支持取消
    this.speechRequestTask = wx.request({
      url: 'http://82.157.209.238:5000/api/tts', // 已改为HTTPS（必须）
      method: 'POST',
      data: { text: text },
      header: { 'Content-Type': 'application/json' },
      timeout: 60000, // 超时时间60秒
      success: (res) => {
        if (this.data.cancelRequest) return; // 已取消则不处理

        if (res.data.success) {
          // 成功获取音频，调用播放方法
          this.playAudio(res.data.audio_base64);
        } else {
          wx.showToast({
            title: res.data.error || '语音合成失败',
            icon: 'none'
          });
        }
      },
      fail: (err) => {
        if (this.data.cancelRequest) return;

        console.error('语音合成接口调用失败:', err);
        // 细化错误提示
        let errorMsg = '网络请求失败';
        if (err.errMsg.includes('timeout')) {
          errorMsg = '合成超时，请稍后重试';
        } else if (err.errMsg.includes('ssl') || err.errMsg.includes('http')) {
          errorMsg = '请使用HTTPS协议';
        }
        wx.showToast({ title: errorMsg, icon: 'none' });
      },
      complete: () => {
        if (!this.data.cancelRequest) {
          this.setData({ AIloading: false });
        }
      }
    });
  },

  /**
   * 取消语音合成请求
   */
  cancelSynthesis() {
    if (this.data.AIloading && this.speechRequestTask) {
      this.speechRequestTask.abort(); // 终止请求
      this.setData({ 
        AIloading: false, 
        cancelRequest: true,
        audioPlaying: false 
      });
      wx.showToast({ title: '已取消合成', icon: 'none' });
    }
  },

  /**
   * 播放音频（处理Base64格式音频）
   */
  playAudio(base64Data) {
    // 移除Base64前缀
    const pureBase64 = base64Data.replace(/^data:audio\/\w+;base64,/, '');
    // 转换为ArrayBuffer
    const buffer = wx.base64ToArrayBuffer(pureBase64);

    // 生成临时文件路径并记录
    const timestamp = Date.now();
    const tempPcmPath = `${wx.env.USER_DATA_PATH}/tts_${timestamp}.pcm`;
    const tempWavPath = `${wx.env.USER_DATA_PATH}/tts_${timestamp}.wav`;
    this.setData({ tempPcmPath, tempWavPath });

    // 写入PCM文件
    const fs = wx.getFileSystemManager();
    fs.writeFile({
      filePath: tempPcmPath,
      data: buffer,
      encoding: 'binary',
      success: () => {
        // 转换为WAV并播放
        this.convertPcmToWav(tempPcmPath, tempWavPath, () => {
          this.audioCtx.src = tempWavPath;
          this.audioCtx.play();
          this.setData({ audioPlaying: true }); // 标记播放中
        });
      },
      fail: (err) => {
        console.error('音频文件写入失败:', err);
        wx.showToast({ title: '音频处理失败', icon: 'none' });
        this.cleanupAudio(); // 失败时清理
      }
    });
  },

  /**
   * 停止当前播放
   */
  stopAudio() {
    if (this.audioCtx && this.data.audioPlaying) {
      this.audioCtx.stop();
      this.setData({ audioPlaying: false });
    }
  },

  /**
   * PCM转WAV（优化数据复制效率）
   */
  convertPcmToWav(pcmPath, wavPath, callback) {
    const fs = wx.getFileSystemManager();
    fs.readFile({
      filePath: pcmPath,
      success: (res) => {
        const pcmData = res.data;
        const sampleRate = 24000; // 与服务器采样率一致
        const bitDepth = 16; // 16位采样
        const numChannels = 1; // 单声道

        // 构建WAV文件头（44字节）
        const buffer = new ArrayBuffer(44 + pcmData.byteLength);
        const view = new DataView(buffer);

        // RIFF chunk
        view.setUint8(0, 0x52); // 'R'
        view.setUint8(1, 0x49); // 'I'
        view.setUint8(2, 0x46); // 'F'
        view.setUint8(3, 0x46); // 'F'
        view.setUint32(4, 36 + pcmData.byteLength, true);
        view.setUint8(8, 0x57); // 'W'
        view.setUint8(9, 0x41); // 'A'
        view.setUint8(10, 0x56); // 'V'
        view.setUint8(11, 0x45); // 'E'

        // fmt subchunk
        view.setUint8(12, 0x66); // 'f'
        view.setUint8(13, 0x6d); // 'm'
        view.setUint8(14, 0x74); // 't'
        view.setUint8(15, 0x20); // ' '
        view.setUint32(16, 16, true); // PCM格式
        view.setUint16(20, 1, true); // 线性PCM
        view.setUint16(22, numChannels, true);
        view.setUint32(24, sampleRate, true);
        view.setUint32(28, sampleRate * numChannels * (bitDepth / 8), true);
        view.setUint16(32, numChannels * (bitDepth / 8), true);
        view.setUint16(34, bitDepth, true);

        // data subchunk
        view.setUint8(36, 0x64); // 'd'
        view.setUint8(37, 0x61); // 'a'
        view.setUint8(38, 0x74); // 't'
        view.setUint8(39, 0x61); // 'a'
        view.setUint32(40, pcmData.byteLength, true);

        // 优化：批量复制PCM数据（替代for循环）
        const pcmView = new Uint8Array(pcmData);
        const wavView = new Uint8Array(buffer);
        wavView.set(pcmView, 44); // 从第44字节开始写入

        // 写入WAV文件
        fs.writeFile({
          filePath: wavPath,
          data: buffer,
          encoding: 'binary',
          success: callback,
          fail: (err) => {
            console.error('WAV文件转换失败:', err);
            wx.showToast({ title: '音频格式转换失败', icon: 'none' });
            this.cleanupAudio(); // 失败时清理
          }
        });
      },
      fail: (err) => {
        console.error('读取PCM文件失败:', err);
        this.cleanupAudio(); // 失败时清理
      }
    });
  },

  /**
   * 清理音频资源（删除临时文件+重置状态）
   */
  cleanupAudio() {
    const { tempPcmPath, tempWavPath } = this.data;
    const fs = wx.getFileSystemManager();

    // 尝试删除临时文件（忽略删除失败的错误）
    if (tempPcmPath) {
      try { fs.unlinkSync(tempPcmPath); } catch (e) { /* 忽略错误 */ }
    }
    if (tempWavPath) {
      try { fs.unlinkSync(tempWavPath); } catch (e) { /* 忽略错误 */ }
    }

    // 重置临时文件路径
    this.setData({
      tempPcmPath: '',
      tempWavPath: ''
    });
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady() {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow() {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide() {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload() {
    // 销毁音频上下文，释放资源
    if (this.audioCtx) {
      this.audioCtx.destroy();
      this.audioCtx = null;
    }
    // 确保临时文件被删除
    this.cleanupAudio();
  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh() {

  },

  /**
   * 页面上拉触底事件的处理函数
   */

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage() {

  },

})    